const sMD5 = require('md5.js')
var Bluetooth = {};
let devices = []
let connected = false
let meter = null
let chs = []
let writedeviceId = null
let writeName = null
let worktype = 0
let randomPassword = null //随机秘钥
let _deviceId = null
let _worktype = null
let _serviceId = null
let _characteristicId = null

Bluetooth.ConnectTo = function (deviceId, name, worktype, callback) {
  console.log(callback);
  let that = this
  writedeviceId = deviceId
  writeName = name
  if (worktype == 1 || worktype == 2) {
    this.getBLEDeviceServices(deviceId, worktype, name, callback)
  } else {
    wx.createBLEConnection({
      deviceId,
      success: (res) => {
        _deviceId = deviceId
        console.log('建立连接')
        this.getBLEDeviceServices(deviceId, worktype, name, callback)
      },
      fail(res) {
        wx.hideLoading({
          success: (res) => {},
        })
        wx.showToast({
          title: '连接失败',
          icon: 'error',
        })
        clearTimeout(meter)
      }
    })
    this.stopBluetoothDevicesDiscovery(callback)
  }
}
Bluetooth.getBLEDeviceServices = function (deviceId, worktype, name, callback) {
  console.log(callback);
  wx.getBLEDeviceServices({
    deviceId,
    success: (res) => {
      for (let i = 0; i < res.services.length; i++) {
        // console.log(res.services[i].uuid + ",isPrimary:" + res.services[i].isPrimary)
        if (res.services[i].uuid == '0000FEE8-0000-1000-8000-00805F9B34FB') {
          this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid, worktype, name, callback)
          return
        }
      }
    }
  })
}

Bluetooth.getBLEDeviceCharacteristics = function (deviceId, serviceId, worktype, name, callback) {
  wx.getBLEDeviceCharacteristics({
    deviceId,
    serviceId,
    success: (res) => {
      // console.log('getBLEDeviceCharacteristics success', res.characteristics)
      for (let i = 0; i < res.characteristics.length; i++) {
        let item = res.characteristics[i]
        if ((worktype == 1 || worktype == 3) && item.uuid == '0000FEC9-0000-1000-8000-00805F9B34FB') { //0000FEC9-0000-1000-8000-00805F9B34FB
          // console.log("read=true,特性UUID:" + item.uuid + ",特性值" + item.value)
          _worktype = worktype
          wx.readBLECharacteristicValue({
            deviceId,
            serviceId,
            characteristicId: item.uuid,
          })
        }
        if ((worktype == 0 || worktype == 2) && item.uuid == '0000FEC7-0000-1000-8000-00805F9B34FB') { //0000FEC6-0000-1000-8000-00805F9B34FB|0000FEC7-0000-1000-8000-00805F9B34FB
          _deviceId = deviceId
          _serviceId = serviceId
          _characteristicId = item.uuid
          this.writeBLECharacteristicValue(worktype, deviceId, name, callback)
        }
      }
      // }
    },
    fail(res) {
      console.error('getBLEDeviceCharacteristics', res)
    }
  })

  // 操作之前先监听，保证第一时间获取数据
  wx.onBLECharacteristicValueChange((characteristic) => {
    const view = new DataView(characteristic.value); //f8003592618804686eee0eac0000000000000000

    console.log(new Date() + "  收到返回:" + ab2hex(characteristic.value))
    // console.log("getUint8:" + view.getUint8(1))
    let that = this
    if (_worktype == 1) {
      if (view.getUint8(1) == 0x00) {
        randomPassword = new ArrayBuffer(4)
        let dataView = new DataView(randomPassword)
        let index = 0
        dataView.setUint8(index++, view.getUint8(7)) //随机秘钥
        dataView.setUint8(index++, view.getUint8(8)) //随机秘钥
        dataView.setUint8(index++, view.getUint8(9)) //随机秘钥
        dataView.setUint8(index++, view.getUint8(10)) //随机秘钥

        setTimeout(function () {
          that.ConnectTo(writedeviceId, writeName, 2, callback)
        }, "200")
      } else {

      }

    } else if (_worktype == 3) {
      wx.hideLoading({
        success: (res) => {},
      })

      if (view.getUint8(1) == 0x00) {
        callback({
          "state": "OK",
          "mac": writeName
        })
        // closeBluetooth();
        console.log("开门成功:")
      } else {
        console.log("开门失败:")
        callback({
          state: "002",
          mac: "nil"
        });
      }
      clearTimeout(meter)
      this.closeBLEConnection()
    }
  })
}

function ab2hex(buffer) {
  var hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('').toUpperCase();
}
Bluetooth.closeBLEConnection = function () {
  console.log('断开连接')
  wx.closeBLEConnection({
    deviceId: _deviceId
  })
  connected = false
  chs = []
}

// 获取服务的特性
Bluetooth.writeBLECharacteristicValue = function (worktype, deviceId, name, callback) {
  // 向蓝牙设备发送一个0x00的16进制数据
  let buffer
  if (worktype == 0) { //f866359261880028//ac
    buffer = this.getPpasswordData(buffer)
  } else {
    buffer = this.getOpendoorData(buffer)
  }
  let that = this
  console.log(new Date() + "  发送数据:" + ab2hex(buffer))
  wx.writeBLECharacteristicValue({
    deviceId: _deviceId,
    serviceId: _serviceId,
    characteristicId: _characteristicId,
    value: buffer,
    success(res) {
      setTimeout(function () {
        that.ConnectTo(deviceId, name, worktype == 0 ? 1 : 3, callback)
      }, "500")
    },
    fail(res) {
      wx.hideLoading({
        success: (res) => {},
      })
      callback({
        state: "003",
        mac: "nil"
      });
      clearTimeout(meter)
    }
  })
}
// 发送命令
Bluetooth.getPpasswordData = function () {
  let buffer = new ArrayBuffer(8)
  let dataView = new DataView(buffer)
  let comPassworddataView = this.getComPassword()
  let index = 0
  dataView.setUint8(index++, 0XF8)
  dataView.setUint8(index++, 0X66) //获取随机秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(0)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(1)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(2)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(3)) //通讯秘钥
  dataView.setUint8(index++, 0X00)
  dataView.setUint8(index++, this.getChk(dataView))

  return buffer
}

Bluetooth.getOpendoorData = function () {

  let buffer = new ArrayBuffer(20)
  let dataView = new DataView(buffer)

  let comPassworddataView = this.getComPassword()
  let cardnoataView = this.getCardNo()
  let macbuffer = this.getMac()
  let macataView = new DataView(macbuffer)
  let index = 0
  dataView.setUint8(index++, 0XF8)
  dataView.setUint8(index++, 0X67) //开门
  dataView.setUint8(index++, comPassworddataView.getUint8(0)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(1)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(2)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(3)) //通讯秘钥
  dataView.setUint8(index++, 12) //长度
  dataView.setUint8(index++, cardnoataView.getUint8(0)) //卡号
  dataView.setUint8(index++, cardnoataView.getUint8(1)) //卡号
  dataView.setUint8(index++, cardnoataView.getUint8(2)) //卡号
  dataView.setUint8(index++, cardnoataView.getUint8(3)) //卡号
  dataView.setUint8(index++, macataView.getUint8(8)) //MAC
  dataView.setUint8(index++, macataView.getUint8(9)) //MAC
  dataView.setUint8(index++, macataView.getUint8(10)) //MAC
  dataView.setUint8(index++, macataView.getUint8(11)) //MAC
  dataView.setUint8(index++, macataView.getUint8(12)) //MAC
  dataView.setUint8(index++, macataView.getUint8(13)) //MAC
  dataView.setUint8(index++, macataView.getUint8(14)) //MAC
  dataView.setUint8(index++, macataView.getUint8(15)) //MAC
  dataView.setUint8(index++, this.getChk(dataView))
  return buffer
}
Bluetooth.getCardNo = function () { //卡号,需要后端获取,这里写死了
  let buffer = new ArrayBuffer(20)
  let dataView = new DataView(buffer)
  let index = 0
  dataView.setUint8(index++, 0x1C) //卡号
  dataView.setUint8(index++, 0x63) //卡号
  dataView.setUint8(index++, 0x70) //卡号
  dataView.setUint8(index++, 0x2B) //卡号
  return dataView
}

Bluetooth.getMac = function () {
  let randomPassworddataView = new DataView(randomPassword)
  let buffer = new ArrayBuffer(16)
  let dataView = new DataView(buffer)
  let comPassworddataView = this.getComPassword()
  let carddataView = this.getCardNo()
  let index = 0
  dataView.setUint8(index++, comPassworddataView.getUint8(0)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(1)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(2)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(3)) //通讯秘钥

  dataView.setUint8(index++, carddataView.getUint8(0)) //卡号
  dataView.setUint8(index++, carddataView.getUint8(1)) //卡号
  dataView.setUint8(index++, carddataView.getUint8(2)) //卡号
  dataView.setUint8(index++, carddataView.getUint8(3)) //卡号

  dataView.setUint8(index++, randomPassworddataView.getUint8(0)) //随机秘钥
  dataView.setUint8(index++, randomPassworddataView.getUint8(1)) //随机秘钥
  dataView.setUint8(index++, randomPassworddataView.getUint8(2)) //随机秘钥
  dataView.setUint8(index++, randomPassworddataView.getUint8(3)) //随机秘钥

  dataView.setUint8(index++, comPassworddataView.getUint8(0)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(1)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(2)) //通讯秘钥
  dataView.setUint8(index++, comPassworddataView.getUint8(3)) //通讯秘钥
  return this.HexString2Bytes(sMD5.hexMD5(ab2hex(buffer)))
}

Bluetooth.HexString2Bytes = function (str) {
  var pos = 0;
  var len = str.length;
  if (len % 2 != 0) {
    return null;
  }
  len /= 2;
  var arrBytes = new ArrayBuffer(len);
  let dataView = new DataView(arrBytes)
  for (var i = 0; i < len; i++) {
    var s = str.substr(pos, 2);
    var v = parseInt(s, 16);
    dataView.setUint8(i, v)
    pos += 2;
  }
  return arrBytes;
}
Bluetooth.getChk = function (dataView) {
  let chk = dataView.getUint8(1)
  for (let i = 2; i < dataView.getUint8(6) + 7; i++) {
    chk = chk ^ dataView.getUint8(i)
  }
  return chk
}
// 读取蓝牙返回值
//监听消息
Bluetooth.getComPassword = function () { //通讯秘钥,需要后端获取,这里写死了
  let buffer = new ArrayBuffer(20)
  let dataView = new DataView(buffer)
  let index = 0
  dataView.setUint8(index++, 0x35) //通讯秘钥
  dataView.setUint8(index++, 0x92) //通讯秘钥
  dataView.setUint8(index++, 0x61) //通讯秘钥
  dataView.setUint8(index++, 0x88) //通讯秘钥
  return dataView
}

Bluetooth.stopBluetoothDevicesDiscovery = function () {
  wx.stopBluetoothDevicesDiscovery({
    success: function (res) {

    },
    fail: function (res) {

    }
  })
}

// 转换
Bluetooth.str2ab = function (str) {
  var buf = new ArrayBuffer(str.length);
  var bufView = new Uint8Array(buf);
  for (var i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

Bluetooth.str2abInbleX = function (str) {
  var buf = new ArrayBuffer(str.length);
  var bufView = new Uint16Array(buf);
  for (var i = 0; i < str.length; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

Bluetooth.ab2str = function ab2str(buf) {
  return String.fromCharCode.apply(null, new Uint8Array(buf));
}


module.exports = Bluetooth;